<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>中介者模式</title>
</head>
<body>
<select id="colorSelect">
    <option value="">请选择颜色</option>
    <option value="red">红色</option>
    <option value="blue">蓝色</option>
</select>
<br/>
<select id="memorySelect">
    <option value="">请选择内存</option>
    <option value="8G">8G</option>
    <option value="16G">16G</option>
    <option value="32G">32G</option>
</select>
<br/>
<input type="text" id="numberInput"/>
<br/>
<div id="colorInfo"></div>
<div id="memoryInfo"></div>
<div id="numberInfo"></div>
<button id="nextBtn" disabled>请选择手机颜色和购买数量</button>
<script>
  /*
  const colorSelect = document.getElementById('colorSelect')
  const numberInput = document.getElementById('numberInput')
  const colorInfo = document.getElementById('colorInfo')
  const numberInfo = document.getElementById('numberInfo')
  const nextBtn = document.getElementById('nextBtn')
  const goods = {
    red: 3,
    blue: 6
  }

  colorSelect.onchange = function () {
    const color = this.value
    const number = numberInput.value
    const stock = goods[color]

    colorInfo.innerHTML = color

    if (!color) {
      nextBtn.disabled = true
      nextBtn.innerHTML = '请选择手机颜色'
      return
    }

    if (((number - 0) | 0) !== number - 0) {
      nextBtn.disabled = true
      nextBtn.innerHTML = '请输入正确的购买数量'
      return
    }

    if (number > stock) {
      nextBtn.disabled = true
      nextBtn.innerHTML = '库存不足'
      return
    }

    nextBtn.disabled = false
    nextBtn.innerHTML = '放入购物车'
  }

  numberInput.oninput = function () {
    const color = colorSelect.value
    const number = numberInput.value
    const stock = goods[color]

    numberInfo.innerHTML = number

    if (!color) {
      nextBtn.disabled = true
      nextBtn.innerHTML = '请选择手机颜色'
      return
    }

    if (((number - 0) | 0) !== number - 0) {
      nextBtn.disabled = true
      nextBtn.innerHTML = '请输入正确的购买数量'
      return
    }

    if (number > stock) {
      nextBtn.disabled = true
      nextBtn.innerHTML = '库存不足'
      return
    }

    nextBtn.disabled = false
    nextBtn.innerHTML = '放入购物车'
  }
  */

  /**
   * 目前每个节点对象都是耦合在一起，改变或增加任何一个节点对象，都要改动其他很多代码
   * 中介者模式可让对象间得以解耦，以中介者和对象间一对多的关系取代了对象间的网状多对多关系
   * 各个对象只需关注自身功能的实现，对象间的交互关系交给中介者来实现和维护
   * 中介者的实现有两种方式：
   * 1.利用发布-订阅模式，中介者为订阅者，每个对象为发布者，一旦对象状态改变，
   *   便推送消息给中介者，中介者处理消息后将反馈发送给其他对象
   * 2.在中介者中开放一些接收消息的接口，各对象可直接调用该接口来发送消息，
   *   同时将自身作为参数传入，以便中介者分辨是谁发生了改变
   * 引入中介者后，无论是修改还是增加新节点，都只需改动中介者对象里的代码
   */

  const colorSelect = document.getElementById('colorSelect')
  const numberInput = document.getElementById('numberInput')
  const memorySelect = document.getElementById('memorySelect')
  const colorInfo = document.getElementById('colorInfo')
  const memoryInfo = document.getElementById('memoryInfo')
  const numberInfo = document.getElementById('numberInfo')
  const nextBtn = document.getElementById('nextBtn')
  const goods = {
    red: 3,
    blue: 6
  }
  const mediator = (function () {
    return {
      changed(obj) {
        const color = colorSelect.value
        const number = numberInput.value
        const memory = memorySelect.value
        const stock = goods[color]

        if (obj === colorSelect) {
          colorInfo.innerHTML = color
        } else if (obj === numberInput) {
          numberInfo.innerHTML = number
        } else if (obj === memorySelect) {
          memoryInfo.innerHTML = memory
        }

        if (!color) {
          nextBtn.disabled = true
          nextBtn.innerHTML = '请选择手机颜色'
          return
        }

        if (!memory) {
          nextBtn.disabled = true
          nextBtn.innerHTML = '请选择手机内存'
          return
        }

        if (number === '' || !Number.isInteger(Number(number))) {
          nextBtn.disabled = true
          nextBtn.innerHTML = '请输入正确的购买数量'
          return
        }

        if (number > stock) {
          nextBtn.disabled = true
          nextBtn.innerHTML = '库存不足'
          return
        }

        nextBtn.disabled = false
        nextBtn.innerHTML = '放入购物车'
      }
    }
  }())

  colorSelect.onchange = function () {
    mediator.changed(this)
  }
  memorySelect.onchange = function () {
    mediator.changed(this)
  }
  numberInput.oninput = function () {
    mediator.changed(this)
  }
</script>
</body>
</html>
